package model

import (
	"fmt"
	"gowork/singleTableOrderRules/utils"
	"strconv"
	"strings"
	"time"
)

type PutOrder struct {
	OrderType int
	CustomerId int64
	CustomerName string
	NextSinglePersonId int64
	NextSinglePersonName string
	MealList string
	TotalPrice int64
	Region string
}

type Order struct {
	OrderId int64 `xorm:"pk autoincr"`
	OrderType int
	OrderState int
	CustomerId int64
	CustomerName string
	NextSinglePersonId int64
	NextSinglePersonName string
	MealList string
	TotalPrice int64
	Region string
	LogisticList []*Logistics `xorm:"-"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Logistics struct {
	Id int64 `xorm:"pk autoincr"`
	CurrentLocation string
	NextLocation string
	ArrivalTime time.Time
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Account struct {
	AccountId int64 `xorm:"pk autoincr"`
	DepartMentId int64
	AccountName string
	Level int
	Incumbency int
	CreatedAt time.Time
	UpdatedAt time.Time
}

func (at *Account)InsertAccount(a *Account) map[string]string{
	x.Insert(a)
	return map[string]string{"message": "成功","code":"200"}
}

func (at *Account)QueryAccountOne(aId int64) Account{
	var a Account
	x.Id(aId).Get(&a)
	return a
}

type Customer struct {
	CustomerId int64 `xorm:"pk autoincr"`
	CustomerName string
	CustomerType int
	FounderId int64
	FounderName string
	BelongerId int64
	BelongerName string
	AllocationTime time.Time
	CreatedAt time.Time
	UpdatedAt time.Time
}

func QueryLogisticInfo(oId int64)([]*Logistics, error){

	var lList []*Logistics
	x.Where("order_id = ?", oId).Find(&lList)

	return lList, nil
}

func (ct *Customer)InsertCustomer(c *Customer) map[string]string{
	x.Insert(c)
	return map[string]string{"message": "成功","code":"200"}
}

func (ct *Customer)QueryCustomerById(cId int64) Customer{
	var c Customer
	x.Id(cId).Get(&c)
	return c
}

func (ct *Customer)QueryCustomerByBloo(cId int64) bool{
	var c *Customer
	x.Id(cId).Get(c)
	if c != nil && time.Now().Sub(c.AllocationTime).Hours()/24 <= 90{
		return true
	}
	return false
}

func (o *Order)QuerytOrder(ot int64, cId int64) Order{
	var ov Order
	x.Where("order_type = ?", ot).And("customer_id = ?", cId).Desc("created_at").Limit(1).Get(&ov)
	return ov
}

func (o *Order)QuerytOrderProductDay(d int, cId int64) []*Order{
	var ov []*Order
	x.Where("customer_id = ?", cId).And("created_at >= ?", time.Now().AddDate(0,0,-d).Format("2006-01-02 15:04:05")).Desc("created_at").Find(&ov)
	return ov
}

func (o *Order)QuerytOrderProductMonth(m int, cId int64) []*Order{
	var ov []*Order
	x.Where("customer_id = ?", cId).And("created_at >= ?", time.Now().AddDate(0,-m,0).Format("2006-01-02 15:04:05")).Desc("created_at").Find(&ov)
	return ov
}

func (o *Order)QuerytOrderProductSum(cId int64) []*Order{
	var ovList []*Order
	x.Where("customer_id = ?", cId).Find(&ovList)
	return ovList
}

func (o *Order)QuerytDateOrder(ot int, td int, cId int64) []*Order{
	var ov []*Order
	x.Where("order_type = ?", ot).And("customer_id = ?", cId).And("created_at >= ?", time.Now().AddDate(0,0,-td).Format("2006-01-02 15:04:05")).
		Desc("created_at").Find(&ov)
	return ov
}

func (o *Order)QuerytOrderList(otId int, cId int64) []*Order{
	var ovList []*Order
	x.Where("order_type = ?", otId).And("customer_id = ?", cId).And("created_at like ?", time.Now().Format("2006-01")+"%").Find(&ovList)
	return ovList
}

func (o *Order)QuerytOrderYearList(otId int, cId int64) []*Order{
	var ovList []*Order
	x.Where("order_type = ?", otId).And("customer_id = ?", cId).Find(&ovList)
	return ovList
}

type Rule struct {
	Id int64 `xorm:"pk autoincr"`
	OrderType int
	Department string
	OCOrderInterval int
	OCSingleOrderMaxAmount int64
	OCSOMAExclusivePackage string
	OCPerMonthOrderMaxAmount int64
	OCPMOMAExclusivePackage string
	OCCumulativeOrderMaxAmount int64
	OCCOMAExclusivePackage string
	INCOrderInterval int
	INCSingleOrderMaxAmount int64
	INCSOMAExclusivePackage string
	INCPerMonthOrderMaxAmount int64
	INCPMOMAExclusivePackage string
	INCCumulativeOrderMaxAmount int64
	INCCOMAExclusivePackage string
	State int  //  1启用  2 停用
	CreatedAt time.Time
	UpdatedAt time.Time
}

type ProductPurchaseRestrictions struct {
	Id int64 `xorm:"pk autoincr"`
	ProductId int64
	ProductName string
	IntervalRestriction int // 1 勾选   2  未勾选
	Interval int
	RestrictionType int
	IntervalLimit int
	SumRestriction int // 1 勾选   2  未勾选
	SumLimit int
	State int  //  1启用  2 停用
	CreatedAt time.Time
	UpdatedAt time.Time
}

func (ppr *ProductPurchaseRestrictions)QueryProduct(pId int64) ProductPurchaseRestrictions{
	var pdr ProductPurchaseRestrictions
	x.Where("product_id = ?", pId).And("state = ?", 1).Get(&pdr)
	return pdr
}

func (order *Order)InsertOrder(po *PutOrder)(map[string]interface{}, error){

	var o *Order
	var a *Account
	var c *Customer
	var ppr *ProductPurchaseRestrictions

	account := a.QueryAccountOne(po.NextSinglePersonId)
	departMentIdStr := strconv.FormatInt(account.DepartMentId, 10)

	pmStrList := strings.Split(po.MealList, ",")
	customer := c.QueryCustomerById(po.CustomerId)

	monOrderList := o.QuerytOrderList(po.OrderType, po.CustomerId)

	cumulativeOrderList := o.QuerytOrderYearList(po.OrderType, po.CustomerId)

	for _, mv := range pmStrList {
		mAndNum := strings.Split(mv, "*")
		pId, err := strconv.ParseInt(mAndNum[1], 10, 64)
		if err != nil {
			return nil, err
		}

		num, err := strconv.Atoi(mAndNum[3])
		if err != nil {
			return nil, err
		}

		p := ppr.QueryProduct(pId)
		if p.Id != 0 {
			if p.IntervalRestriction == 1 {
				var sumProduct int = 0

				sumProduct += num
				if p.RestrictionType == 1 {
					for _, opv := range o.QuerytOrderProductDay(p.Interval, po.CustomerId) {
						opvMealList := strings.Split(opv.MealList, ",")
						for _, op := range opvMealList {
							opStr := strings.Split(op, "*")
							mId, err := strconv.ParseInt(opStr[1], 10, 64)
							if err != nil {
								return nil, err
							}
							if mId == p.ProductId {
								opNum, err := strconv.Atoi(opStr[3])
								if err != nil {
									return nil, err
								}
								sumProduct += opNum
							}
						}
					}
				} else if p.RestrictionType == 2 {
					for _, opdv := range o.QuerytOrderProductMonth(p.Interval, po.CustomerId) {
						opvMealList := strings.Split(opdv.MealList, ",")
						for _, op := range opvMealList {
							opStr := strings.Split(op, "*")
							mId, err := strconv.ParseInt(opStr[1], 10, 64)
							if err != nil {
								return nil, err
							}
							if mId == p.ProductId {
								opNum, err := strconv.Atoi(opStr[3])
								if err != nil {
									return nil, err
								}
								sumProduct += opNum
							}
						}
					}
				}

				fmt.Println("总数：", sumProduct)
				if sumProduct > p.IntervalLimit {
					return map[string]interface{}{"message": "超过限制数", "code": "400"}, nil
				}
			}

			if p.SumRestriction == 1{
				var sumProduct int = 0
				sumProduct += num

				for _, opdv := range o.QuerytOrderProductSum(po.CustomerId) {
					opvMealList := strings.Split(opdv.MealList, ",")
					for _, op := range opvMealList {
						opStr := strings.Split(op, "*")
						mId, err := strconv.ParseInt(opStr[1], 10, 64)
						if err != nil {
							return nil, err
						}
						if mId == p.ProductId {
							opNum, err := strconv.Atoi(opStr[3])
							if err != nil {
								return nil, err
							}
							sumProduct += opNum
						}
					}
				}

				fmt.Println("总数：", sumProduct)
				if sumProduct > p.SumLimit {
					return map[string]interface{}{"message": "超过限制数", "code": "400"}, nil
				}
			}
		}
	}

	var ruleList []*Rule
	x.Where("order_type = ?", po.OrderType).And("state = ?", 1).Find(&ruleList)
	for _, r := range ruleList{
		if account.AccountId != 0{
			dStrList := strings.Split(r.Department, ",")
			var tem bool = false
			for _, ds := range dStrList{
				if ds == departMentIdStr{
					tem = true
					break
				}
			}
			if tem == true{
				if customer.CustomerType == 1 {
					if r.OCOrderInterval != 0 {
						fmt.Println("订单列表：", o.QuerytDateOrder(po.OrderType, r.OCOrderInterval, po.CustomerId))
						if len(o.QuerytDateOrder(po.OrderType, r.OCOrderInterval, po.CustomerId)) > 0 {
							return map[string]interface{}{"message": "此客户的该类型订单间隔小于" + strconv.Itoa(r.OCOrderInterval) + "天", "code": "400"}, nil
						}
					}

					if r.OCSingleOrderMaxAmount != 0 {
						cepStrList := strings.Split(r.OCSOMAExclusivePackage, ",")

						var sumPrice int64 = 0

						for _, pm := range pmStrList {
							mAndNum := strings.Split(pm, "*")
							for _, cep := range cepStrList {
								if mAndNum[1] == cep {
									pri, err := strconv.ParseInt(mAndNum[2], 10, 64)
									if err != nil {
										return nil, err
									}
									num, err := strconv.ParseInt(mAndNum[3], 10, 64)
									if err != nil {
										return nil, err
									}
									sumPrice += pri * num
								}
							}
						}

						if r.OCSingleOrderMaxAmount < po.TotalPrice - sumPrice {
							return map[string]interface{}{"message": "此类型订单单笔不能超过"+strconv.FormatInt(r.OCSingleOrderMaxAmount, 10)+"元","code":"400"}, nil
						}
					}

					if r.OCPerMonthOrderMaxAmount != 0 {
						cepStrList := strings.Split(r.OCPMOMAExclusivePackage, ",")

						var sumPrice int64 = 0
						var sumHorPrice int64 = 0
						var monOrderPrice int64 = 0

						for _, pm := range pmStrList {
							mAndNum := strings.Split(pm, "*")
							for _, cep := range cepStrList {
								if mAndNum[1] == cep {
									pri, err := strconv.ParseInt(mAndNum[2], 10, 64)
									if err != nil {
										return nil, err
									}
									num, err := strconv.ParseInt(mAndNum[3], 10, 64)
									if err != nil {
										return nil, err
									}
									sumPrice += pri * num
								}
							}
						}

						for _, monOrder := range monOrderList{
							mAndNumHor := strings.Split(monOrder.MealList, ",")
							for _, ahs := range mAndNumHor {
								ah := strings.Split(ahs, "*")
								for _, cep := range cepStrList {
									if ah[1] == cep {
										priHor, err := strconv.ParseInt(ah[2], 10, 64)
										if err != nil {
											return nil, err
										}
										numHor, err := strconv.ParseInt(ah[3], 10, 64)
										if err != nil {
											return nil, err
										}

										sumHorPrice = sumHorPrice + priHor*numHor
									}
								}
							}
							monOrderPrice += monOrder.TotalPrice - sumHorPrice
							sumHorPrice = 0
						}

						if r.OCPerMonthOrderMaxAmount < monOrderPrice + po.TotalPrice - sumPrice {
							return map[string]interface{}{"message": "此类订单每月累计不能超过"+strconv.FormatInt(r.OCPerMonthOrderMaxAmount, 10)+"元","code":"400"}, nil
						}
					}

					if r.OCCumulativeOrderMaxAmount != 0 {
						cepStrList := strings.Split(r.OCCOMAExclusivePackage, ",")

						var sumPrice int64 = 0
						var sumHorPrice int64 = 0
						var cumulativeOrderPrice int64 = 0

						for _, pm := range pmStrList {
							mAndNum := strings.Split(pm, "*")
							for _, cep := range cepStrList {
								if mAndNum[1] == cep {
									pri, err := strconv.ParseInt(mAndNum[2], 10, 64)
									if err != nil {
										return nil, err
									}
									num, err := strconv.ParseInt(mAndNum[3], 10, 64)
									if err != nil {
										return nil, err
									}
									sumPrice += pri * num
								}
							}
						}

						for _, cumulativeOrder := range cumulativeOrderList{
							mAndNumHor := strings.Split(cumulativeOrder.MealList, ",")
							for _, ahs := range mAndNumHor {
								ah := strings.Split(ahs, "*")
								for _, cep := range cepStrList {
									if ah[1] == cep {
										priHor, err := strconv.ParseInt(ah[2], 10, 64)
										if err != nil {
											return nil, err
										}
										numHor, err := strconv.ParseInt(ah[3], 10, 64)
										if err != nil {
											return nil, err
										}

										sumHorPrice = sumHorPrice + priHor*numHor
									}
								}
							}
							cumulativeOrderPrice += cumulativeOrder.TotalPrice - sumHorPrice
							sumHorPrice = 0
						}

						if r.OCCumulativeOrderMaxAmount < cumulativeOrderPrice + po.TotalPrice - sumPrice {
							return map[string]interface{}{"message": "此类订单累计不能超过"+strconv.FormatInt(r.OCCumulativeOrderMaxAmount, 10)+"元","code":"400"}, nil
						}
					}

				}else if customer.CustomerType == 2{
					if r.INCOrderInterval != 0 {
						if len(o.QuerytDateOrder(po.OrderType, r.INCOrderInterval, po.CustomerId)) > 0 {
							return map[string]interface{}{"message": "此客户的该类型订单间隔小于" + strconv.Itoa(r.INCOrderInterval) + "天", "code": "400"}, nil
						}
					}

					if r.INCSingleOrderMaxAmount != 0 {
						cepStrList := strings.Split(r.INCSOMAExclusivePackage, ",")

						var sumPrice int64 = 0

						for _, pm := range pmStrList {
							mAndNum := strings.Split(pm, "*")
							for _, cep := range cepStrList {
								if mAndNum[1] == cep {
									pri, err := strconv.ParseInt(mAndNum[2], 10, 64)
									if err != nil {
										return nil, err
									}
									num, err := strconv.ParseInt(mAndNum[3], 10, 64)
									if err != nil {
										return nil, err
									}
									sumPrice += pri * num
								}
							}
						}

						if r.INCSingleOrderMaxAmount < po.TotalPrice - sumPrice {
							return map[string]interface{}{"message": "此类型订单单笔不能超过"+strconv.FormatInt(r.INCSingleOrderMaxAmount,10)+"元","code":"400"}, nil
						}
					}

					if r.INCPerMonthOrderMaxAmount != 0 {
						cepStrList := strings.Split(r.INCPMOMAExclusivePackage, ",")

						var sumPrice int64 = 0
						var sumHorPrice int64 = 0
						var monOrderPriceTotal int64 = 0

						for _, pm := range pmStrList {
							mAndNum := strings.Split(pm, "*")
							for _, cep := range cepStrList {
								if mAndNum[1] == cep {
									pri, err := strconv.ParseInt(mAndNum[2], 10, 64)
									if err != nil {
										return nil, err
									}
									num, err := strconv.ParseInt(mAndNum[3], 10, 64)
									if err != nil {
										return nil, err
									}
									sumPrice += pri * num
								}
							}
						}

						for _, monOrder := range monOrderList {
							mAndNumHor := strings.Split(monOrder.MealList, ",")
							for _, ahs := range mAndNumHor {
								ah := strings.Split(ahs, "*")
								for _, cep := range cepStrList {
									if ah[1] == cep {
										priHor, err := strconv.ParseInt(ah[2], 10, 64)
										if err != nil {
											return nil, err
										}
										numHor, err := strconv.ParseInt(ah[3], 10, 64)
										if err != nil {
											return nil, err
										}

										sumHorPrice = sumHorPrice + priHor*numHor
									}
								}
							}
							monOrderPriceTotal = monOrderPriceTotal + monOrder.TotalPrice - sumHorPrice
							sumHorPrice = 0
						}

						if r.INCPerMonthOrderMaxAmount < monOrderPriceTotal + po.TotalPrice - sumPrice {
							return map[string]interface{}{"message": "此类订单每月累计不能超过"+strconv.FormatInt(r.INCPerMonthOrderMaxAmount,10)+"元","code":"400"}, nil
						}
					}

					if r.INCCumulativeOrderMaxAmount != 0 {
						cepStrList := strings.Split(r.INCCOMAExclusivePackage, ",")

						var sumPrice int64 = 0
						var sumHorPrice int64 = 0
						var cumulativeOrderPrice int64 = 0

						for _, pm := range pmStrList {
							mAndNum := strings.Split(pm, "*")
							for _, cep := range cepStrList {
								if mAndNum[1] == cep {
									pri, err := strconv.ParseInt(mAndNum[2], 10, 64)
									if err != nil {
										return nil, err
									}
									num, err := strconv.ParseInt(mAndNum[3], 10, 64)
									if err != nil {
										return nil, err
									}
									sumPrice += pri * num
								}
							}
						}

						for _, cumulativeOrder := range cumulativeOrderList {
							mAndNumHor := strings.Split(cumulativeOrder.MealList, ",")
							for _, ahs := range mAndNumHor {
								ah := strings.Split(ahs, "*")
								for _, cep := range cepStrList {
									if ah[1] == cep {
										priHor, err := strconv.ParseInt(ah[2], 10, 64)
										if err != nil {
											return nil, err
										}
										numHor, err := strconv.ParseInt(ah[3], 10, 64)
										if err != nil {
											return nil, err
										}

										sumHorPrice = sumHorPrice + priHor*numHor
									}
								}
							}
							cumulativeOrderPrice += cumulativeOrder.TotalPrice - sumHorPrice
							sumHorPrice = 0
						}

						if r.INCCumulativeOrderMaxAmount < cumulativeOrderPrice + po.TotalPrice - sumPrice {
							return map[string]interface{}{"message": "此类订单累计不能超过"+strconv.FormatInt(r.INCCumulativeOrderMaxAmount, 10)+"元","code":"400"}, nil
						}
					}
				}
			}
		}
	}

	w := new(utils.Worker)

	var ov = Order{
		OrderId:              w.GetId(),
		OrderType:            po.OrderType,
		OrderState:           1,
		CustomerId:           po.CustomerId,
		CustomerName:         po.CustomerName,
		NextSinglePersonId:   po.NextSinglePersonId,
		NextSinglePersonName: po.NextSinglePersonName,
		MealList:             po.MealList,
		TotalPrice:           po.TotalPrice,
		Region:               po.Region,
		CreatedAt:            time.Now(),
		UpdatedAt:            time.Now(),
	}
	x.Insert(&ov)

	return map[string]interface{}{"code":200, "message":"成功"}, nil
}






